import 'dart:convert';
import 'package:meta/meta.dart';
import '../../../constants/enums/device_type.dart';
import '../../../constants/enums/device_status.dart';

/// 设备模型 - 用于存储设备相关信息
class DeviceModel {
  /// 设备ID
  final String id;
  
  /// 设备名称
  final String name;
  
  /// 设备类型
  final DeviceType type;
  
  /// 设备状态（在线/离线/故障等）
  final DeviceStatus status;
  
  /// 设备位置描述
  final String? location;
  
  /// 设备IP地址
  final String? ipAddress;
  
  /// 设备MAC地址
  final String? macAddress;
  
  /// 设备版本号
  final String? version;
  
  /// 设备描述信息
  final String? description;
  
  /// 厂商信息
  final String? manufacturer;
  
  /// 设备型号
  final String? model;
  
  /// 设备属性（可动态拓展的设备参数）
  final Map<String, dynamic>? attributes;
  
  /// 设备标签
  final List<String>? tags;
  
  /// 创建时间
  final DateTime createdAt;
  
  /// 更新时间
  final DateTime updatedAt;
  
  /// 上次在线时间
  final DateTime? lastOnlineTime;
  
  /// 是否在线
  bool get isOnline => status == DeviceStatus.online;
  
  /// 是否离线
  bool get isOffline => status == DeviceStatus.offline;
  
  /// 是否故障
  bool get isFault => status == DeviceStatus.fault;
  
  /// 激活日期
  final DateTime? activationDate;
  
  /// 设备属性（如温度、亮度等）
  final Map<String, dynamic>? properties;
  
  /// 设备设置（如灵敏度、阈值等）
  final Map<String, dynamic>? settings;
  
  DeviceModel({
    required this.id,
    required this.name,
    required this.type,
    required this.status,
    this.location,
    this.createdAt,
    this.updatedAt,
    this.ipAddress,
    this.macAddress,
    this.version,
    this.description,
    this.manufacturer,
    this.model,
    this.attributes,
    this.tags,
    this.lastOnlineTime,
    this.activationDate,
    this.properties,
    this.settings,
  });
  
  /// 创建一个空的设备实例
  factory DeviceModel.empty() {
    return DeviceModel(
      id: '',
      name: '',
      type: DeviceType.unknown,
      status: DeviceStatus.unknown,
      location: '',
      createdAt: DateTime.now(),
      updatedAt: DateTime.now(),
    );
  }
  
  /// 从JSON映射创建设备实例
  factory DeviceModel.fromJson(Map<String, dynamic> json) {
    return DeviceModel(
      id: json['id'] as String? ?? '',
      name: json['name'] as String? ?? 'Unknown Device',
      type: DeviceTypeExtension.fromString(json['type'] as String? ?? 'unknown'),
      status: DeviceStatusExtension.fromString(json['status'] as String? ?? 'unknown'),
      location: json['location'] as String?,
      ipAddress: json['ip_address'] as String?,
      macAddress: json['mac_address'] as String?,
      version: json['version'] as String?,
      description: json['description'] as String?,
      manufacturer: json['manufacturer'] as String?,
      model: json['model'] as String?,
      attributes: json['attributes'] != null
          ? (json['attributes'] is String
              ? jsonDecode(json['attributes'] as String) as Map<String, dynamic>
              : json['attributes'] as Map<String, dynamic>)
          : null,
      tags: json['tags'] != null
          ? (json['tags'] is String
              ? (jsonDecode(json['tags'] as String) as List).cast<String>()
              : (json['tags'] as List).cast<String>())
          : null,
      createdAt: json['created_at'] != null
          ? DateTime.parse(json['created_at'] as String)
          : DateTime.now(),
      updatedAt: json['updated_at'] != null
          ? DateTime.parse(json['updated_at'] as String)
          : DateTime.now(),
      lastOnlineTime: json['last_online_time'] != null
          ? DateTime.parse(json['last_online_time'] as String)
          : null,
      activationDate: json['activationDate'] != null
          ? DateTime.tryParse(json['activationDate'] as String)
          : null,
      properties: json['properties'] as Map<String, dynamic>?,
      settings: json['settings'] as Map<String, dynamic>?,
    );
  }
  
  /// 转换为JSON映射
  Map<String, dynamic> toJson() {
    return {
      'id': id,
      'name': name,
      'type': type.toString().split('.').last,
      'status': status.toString().split('.').last,
      'location': location,
      'ip_address': ipAddress,
      'mac_address': macAddress,
      'version': version,
      'description': description,
      'manufacturer': manufacturer,
      'model': model,
      'attributes': attributes != null ? jsonEncode(attributes) : null,
      'tags': tags != null ? jsonEncode(tags) : null,
      'created_at': createdAt.toIso8601String(),
      'updated_at': updatedAt.toIso8601String(),
      'last_online_time': lastOnlineTime?.toIso8601String(),
      'activationDate': activationDate?.toIso8601String(),
      'properties': properties,
      'settings': settings,
    };
  }
  
  /// 创建一个副本对象
  DeviceModel copyWith({
    String? id,
    String? name,
    DeviceType? type,
    DeviceStatus? status,
    String? location,
    String? ipAddress,
    String? macAddress,
    String? version,
    String? description,
    String? manufacturer,
    String? model,
    Map<String, dynamic>? attributes,
    List<String>? tags,
    DateTime? createdAt,
    DateTime? updatedAt,
    DateTime? lastOnlineTime,
    DateTime? activationDate,
    Map<String, dynamic>? properties,
    Map<String, dynamic>? settings,
  }) {
    return DeviceModel(
      id: id ?? this.id,
      name: name ?? this.name,
      type: type ?? this.type,
      status: status ?? this.status,
      location: location ?? this.location,
      ipAddress: ipAddress ?? this.ipAddress,
      macAddress: macAddress ?? this.macAddress,
      version: version ?? this.version,
      description: description ?? this.description,
      manufacturer: manufacturer ?? this.manufacturer,
      model: model ?? this.model,
      attributes: attributes ?? this.attributes,
      tags: tags ?? this.tags,
      createdAt: createdAt ?? this.createdAt,
      updatedAt: updatedAt ?? this.updatedAt,
      lastOnlineTime: lastOnlineTime ?? this.lastOnlineTime,
      activationDate: activationDate ?? this.activationDate,
      properties: properties ?? this.properties,
      settings: settings ?? this.settings,
    );
  }
  
  @override
  String toString() {
    return 'DeviceModel(id: $id, name: $name, type: ${type.toString().split('.').last}, status: ${status.toString().split('.').last})';
  }
} 